// file:lib\list.h>
// autor:jiang xinpeng
// time:2020.12.23
// copyright:(C) 2020-2050 by jiang xinpeng,All right are reserved.

#include <os/debug.h>
#include <lib/list.h>
#include <lib/stddef.h>

void list_init(struct list *head)
{
    head->prior = head;
    head->next = head;
}


void list_del(struct list *del)
{
    // clean connect relationship
    del->prior->next = del->next;
    del->next->prior = del->prior;
    // clean point
    del->next = NULL;
    del->prior = NULL;
}

void list_del_init(struct list *del)
{
    // del node
    list_del(del);
    // init to head
    list_init(del);
}

void list_replace(struct list *old, struct list *new)
{
    // replace
    new->next = old->next;
    old->next->prior = new;
    new->prior = old->prior;
    old->prior->next = new;
    // clean
    old->prior = NULL;
    old->next = NULL;
}

void list_replace_init(struct list *old, struct list *new)
{
    // replace
    list_replace(old, new);
    // init list head
    list_init(old);
}

// check list if is empty
int list_empty(struct list *head)
{
    if (head->next == head && head->prior == head)
        return 1;
    return 0;
}



// move node to head after
void list_move_after(struct list *node, struct list *head)
{
    // del node
    list_del(node);
    // add to head node after
    list_add_after(node, head);
}

// move node to head before
void list_move_befor(struct list *node, struct list *head)
{
    // del node
    list_del(node);
    // insert to head before
    list_add_before(node, head);
}

// find assume node
int list_find(struct list *list, struct list *head)
{
    struct list *pos;
    list_traversal_all_to_next(head, pos)
    {
        if (pos == list)
            return 1;
    }
    return 0;
}

// get list length
int list_length(struct list *head)
{
    struct list *pos = NULL;
    int count = 0;

    list_traversal_all_to_next(head, pos)
    {
        if (pos == head)
            break;
        count++;
    }
    return count;
}

int list_is_head(struct list *list)
{
    if ((list->next != list) && (list->prior != list))
        return 0;
    return 1;
}
